//
//  MDHViewController.m
//  MDHPT
//
//  Created by 高得华 on 2019/4/27.
//  Copyright © 2019年 高得华. All rights reserved.
//

#import "MDHViewController.h"
#import "MDHNavigationController.h"
///侧滑手势
#if __has_include(<FDFullscreenPopGesture/UINavigationController+FDFullscreenPopGesture.h>)
#import <FDFullscreenPopGesture/UINavigationController+FDFullscreenPopGesture.h>
#else
#import "UINavigationController+FDFullscreenPopGesture.h"
#endif
///键盘管理者
#if __has_include(<IQKeyboardManager/IQKeyboardManager.h>)
#import <IQKeyboardManager/IQKeyboardManager.h>
#else
#import "IQKeyboardManager.h"
#endif
#import "WRNavigationBar.h"
#import "MDHFileConstant.h"
#import "MDHMacroHeader.h"

@interface MDHViewController ()

// viewModel
@property (nonatomic, readwrite, strong) MDHViewModel *viewModel;

@end

@implementation MDHViewController

- (void)dealloc {
    /// 销毁时保存数据
    //[SBPhotoManager configureSelectOriginalPhoto:_isSelectOriginalPhoto];
    DTLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));
}

// when `BaseViewController ` created and call `viewDidLoad` method , execute `bindViewModel` method
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    MDHViewController *viewController = [super allocWithZone:zone];
    @weakify(viewController)
    [[viewController
      rac_signalForSelector:@selector(viewDidLoad)]
     subscribeNext:^(id x) {
         @strongify(viewController)
         [viewController bindViewModel];
     }];
    return viewController;
}

- (instancetype)initWithViewModel:(MDHViewModel *)viewModel {
    self = [super init];
    if (self) {
        self.viewModel = viewModel;
    }
    return self;
}

//- (void)loadView {
//    UIScrollView * sv = [[UIScrollView alloc] initWithFrame:[UIScreen mainScreen].bounds];
//    self.view = sv;
//}

- (void)viewDidLoad {
    [super viewDidLoad];
    /// ignore adjust auto scroll 64
    /// CoderMikeHe: 适配 iOS 11.0 ,iOS11以后，控制器的automaticallyAdjustsScrollViewInsets已经废弃，所以默认就会是YES
    /// iOS 11新增：adjustContentInset 和 contentInsetAdjustmentBehavior 来处理滚动区域
    ///
    if (@available(iOS 11.0, *)) {
        self.automaticallyAdjustsScrollViewInsets = true;
    }else{
        self.automaticallyAdjustsScrollViewInsets = false;
    }
    
    self.extendedLayoutIncludesOpaqueBars = true;
    /// backgroundColor
    self.view.backgroundColor = [UIColor whiteColor];
    //self.view.backgroundColor = kColor_MDHEEEEEE();//[UIColor whiteColor];

    /// 导航栏隐藏 只能在ViewDidLoad里面加载，无法动态
    self.fd_prefersNavigationBarHidden = self.viewModel.prefersNavigationBarHidden;
    
    /// pop手势
    self.fd_interactivePopDisabled = self.viewModel.interactivePopDisabled;
    
    /// 先记录
    //self.isSelectOriginalPhoto = [SBPhotoManager isSelectOriginalPhoto];
    
    /// 后重置
    //[SBPhotoManager configureSelectOriginalPhoto:NO];
    
//    UIScrollView * sv = (UIScrollView *)self.view;
//    sv.backgroundColor = [UIColor redColor];
//    sv.contentSize = CGSizeMake(kMDH_SCREEN_WIDTH(), kMDH_SCREEN_HEIGHT());
}


- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    /// 隐藏导航栏细线
    self.viewModel.prefersNavigationBarBottomLineHidden?[(MDHNavigationController *)self.navigationController hideNavigationBottomLine]:[(MDHNavigationController *)self.navigationController showNavigationBottomLine];
    [self wr_setNavBarShadowImageHidden:self.viewModel.prefersNavigationBarBottomLineHidden];
    /// 配置键盘
    IQKeyboardManager.sharedManager.enable = self.viewModel.keyboardEnable;
    IQKeyboardManager.sharedManager.shouldResignOnTouchOutside = self.viewModel.shouldResignOnTouchOutside;
    IQKeyboardManager.sharedManager.keyboardDistanceFromTextField = self.viewModel.keyboardDistanceFromTextField;
    IQKeyboardManager.sharedManager.enableAutoToolbar = self.viewModel.keyboardEnableAutoToolbar;
    
    /// 这里做友盟统计
    //[MobClick beginLogPageView:SBPageName(self)];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    
    [self.viewModel.willDisappearSignal sendNext:nil];
    
    // Being popped, take a snapshot
    if ([self isMovingFromParentViewController]) {
        self.snapshot = [self.navigationController.view snapshotViewAfterScreenUpdates:false];
    }
    
    /// 这里做友盟统计
    //[MobClick endLogPageView:SBPageName(self)];
}


// bind the viewModel
- (void)bindViewModel {
    /// set navgation title
    /// CoderMikeHe Fixed: 这里只是单纯设置导航栏的title。 不然以免self.title同时设置了navigatiItem.title, 同时又设置了tabBarItem.title
    @weakify(self);
    __weak typeof(self) weakSelf = self;
    RAC(self.navigationItem , title) = RACObserve(self, viewModel.title);
    [[[RACObserve(self.viewModel, interactivePopDisabled) distinctUntilChanged] deliverOnMainThread] subscribeNext:^(NSNumber * x) {
        @strongify(self);
        self.fd_interactivePopDisabled = x.boolValue;
    }];
    /// 绑定错误信息
    [self.viewModel.errors subscribeNext:^(NSError *error) {
        /// 这里可以统一处理某个错误，例如用户授权失效的的操作
        @strongify(self);
        NSInteger code = error.code;
        if (code == 403) {///Token失效
            //DismissHud(self.view);
            //ShowHUDMesHidden(error.userInfo[MHHTTPServiceErrorMessagesKey], self.view);
            AlertViewShowOneTB(@"提示", @"Token已过期,请重新登录", ^(int index) {
                /// 删除账号
                [SAMKeychain deleteRawLogin];
                /// 先退出用户
                [self.viewModel.services.client logoutUser];
                /// 这里切换 到账号登录的界面
                [[NSNotificationCenter defaultCenter] postNotificationName:kNotification_LoginSuccess object:nil];
            });
        }
        //DTLog(@"%@",self.viewModel.services.client.token);
        DTLog(@"...错误...");
    }];
    ///键盘消失
    [[weakSelf.viewModel.subKeyboardHidden deliverOnMainThread] subscribeNext:^(id x) {
        //@strongify(self);
        [weakSelf.view endEditing:true];
    }];
}

#pragma mark - Orientation
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {return UIInterfaceOrientationMaskPortrait;}
- (BOOL)shouldAutorotate {return false;}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {return UIInterfaceOrientationPortrait;}

#pragma mark - Status bar
- (BOOL)prefersStatusBarHidden { return false; }
- (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleDefault; }
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation { return UIStatusBarAnimationFade; }


//MARK: - === JXPagerViewListViewDelegate
/**
 返回listView。如果是vc包裹的就是vc.view；如果是自定义view包裹的，就是自定义view自己。
 
 @return UIView
 */
- (UIView *)listView {
    return self.view;
}

/**
 返回listView内部持有的UIScrollView或UITableView或UICollectionView
 主要用于mainTableView已经显示了header，listView的contentOffset需要重置时，内部需要访问到外部传入进来的listView内的scrollView
 
 @return listView内部持有的UIScrollView或UITableView或UICollectionView
 */
- (UIScrollView *)listScrollView {
    return nil;
}


/**
 当listView内部持有的UIScrollView或UITableView或UICollectionView的代理方法`scrollViewDidScroll`回调时，需要调用该代理方法传入的callback
 
 @param callback `scrollViewDidScroll`回调时调用的callback
 */
- (void)listViewDidScrollCallback:(void (^)(UIScrollView *scrollView))callback { }


//MARK:  - JXPagerViewDelegate
- (UIView *)tableHeaderViewInPagerView:(JXPagerView *)pagerView {
    return nil;
}
- (NSUInteger)tableHeaderViewHeightInPagerView:(JXPagerView *)pagerView {
    return 0;
}
- (NSUInteger)heightForPinSectionHeaderInPagerView:(JXPagerView *)pagerView {
    return 0;
}
- (UIView *)viewForPinSectionHeaderInPagerView:(JXPagerView *)pagerView {
    return nil;
}
- (NSInteger)numberOfListsInPagerView:(JXPagerView *)pagerView {
    //和categoryView的item数量一致
    return 0;
}
- (id<JXPagerViewListViewDelegate>)pagerView:(JXPagerView *)pagerView initListAtIndex:(NSInteger)index {
    return nil;
}

//MARK: - == DZNEmptyDataSetSource
/**
 Asks the data source for the title of the dataset. 设置标题
 The dataset uses a fixed font style by default, if no attributes are set. If you want a different font style, return a attributed string.
 
 @param scrollView A scrollView subclass informing the data source.
 @return An attributed string for the dataset title, combining font, text color, text pararaph style, etc.
 */
- (NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView {
    return [NSAttributedString new];
}

/**
 Asks the data source for the description of the dataset. 设置详情文字
 The dataset uses a fixed font style by default, if no attributes are set. If you want a different font style, return a attributed string.
 
 @param scrollView A scrollView subclass informing the data source.
 @return An attributed string for the dataset description text, combining font, text color, text pararaph style, etc.
 */
- (NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView {
    return [[NSAttributedString alloc] initWithString:@"暂无数据"];
}

/**
 Asks the data source for the image of the dataset. 设置图片
 
 @param scrollView A scrollView subclass informing the data source.
 @return An image for the dataset.
 */
- (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView {
    return [UIImage new];
}


/**
 Asks the data source for a tint color of the image dataset. Default is nil. 改变图片的颜色
 
 @param scrollView A scrollView subclass object informing the data source.
 @return A color to tint the image of the dataset.
 */
- (UIColor *)imageTintColorForEmptyDataSet:(UIScrollView *)scrollView {
    return nil;
}

/**
 *  Asks the data source for the image animation of the dataset. 设置图片的动画
 *
 *  @param scrollView A scrollView subclass object informing the delegate.
 *
 *  @return image animation
 */
- (CAAnimation *) imageAnimationForEmptyDataSet:(UIScrollView *) scrollView {
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
    animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
    animation.toValue = [NSValue valueWithCATransform3D: CATransform3DMakeRotation(M_PI_2, 0.0, 0.0, 1.0) ];
    animation.duration = 0.25;
    animation.cumulative = YES;
    animation.repeatCount = MAXFLOAT;
    return animation;
}

/**
 Asks the data source for the title to be used for the specified button state. 设置按钮不同状态的文字
 The dataset uses a fixed font style by default, if no attributes are set. If you want a different font style, return a attributed string.
 
 @param scrollView A scrollView subclass object informing the data source.
 @param state The state that uses the specified title. The possible values are described in UIControlState.
 @return An attributed string for the dataset button title, combining font, text color, text pararaph style, etc.
 */
- (NSAttributedString *)buttonTitleForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state {
    return [NSAttributedString new];
}

/**
 Asks the data source for the image to be used for the specified button state. 设置按钮不同状态的图片
 This method will override buttonTitleForEmptyDataSet:forState: and present the image only without any text.
 
 @param scrollView A scrollView subclass object informing the data source.
 @param state The state that uses the specified title. The possible values are described in UIControlState.
 @return An image for the dataset button imageview.
 */
- (UIImage *)buttonImageForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state {
    return nil;
}

/**
 Asks the data source for a background image to be used for the specified button state. 设置按钮不同状态的背景图片
 There is no default style for this call.
 
 @param scrollView A scrollView subclass informing the data source.
 @param state The state that uses the specified image. The values are described in UIControlState.
 @return An attributed string for the dataset button title, combining font, text color, text pararaph style, etc.
 */
- (UIImage *)buttonBackgroundImageForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state {
    return nil;
}

/**
 Asks the data source for the background color of the dataset. Default is clear color. ///设置背景颜色
 
 @param scrollView A scrollView subclass object informing the data source.
 @return A color to be applied to the dataset background view.
 */
- (UIColor *)backgroundColorForEmptyDataSet:(UIScrollView *)scrollView {
    return [[UIColor whiteColor] colorWithAlphaComponent:0.001];
}

/** 自定义的 视图
 Asks the data source for a custom view to be displayed instead of the default views such as labels, imageview and button. Default is nil.
 Use this method to show an activity view indicator for loading feedback, or for complete custom empty data set.
 Returning a custom view will ignore -offsetForEmptyDataSet and -spaceHeightForEmptyDataSet configurations.
 
 @param scrollView A scrollView subclass object informing the delegate.
 @return The custom view.
 */
- (UIView *)customViewForEmptyDataSet:(UIScrollView *)scrollView {
    return nil;
}

/** 内容的偏移量
 Asks the data source for a offset for vertical and horizontal alignment of the content. Default is CGPointZero.
 
 @param scrollView A scrollView subclass object informing the delegate.
 @return The offset for vertical and horizontal alignment.
 */
- (CGFloat)verticalOffsetForEmptyDataSet:(UIScrollView *)scrollView {
    return 0;
}

/** 之间的距离
 Asks the data source for a vertical space between elements. Default is 11 pts.
 
 @param scrollView A scrollView subclass object informing the delegate.
 @return The space height between elements.
 */
- (CGFloat)spaceHeightForEmptyDataSet:(UIScrollView *)scrollView {
    return 11;
}


//MARK: - == DZNEmptyDataSetDelegate
/** 空数据集是否应在显示时淡入
 Asks the delegate to know if the empty dataset should fade in when displayed. Default is YES.
 
 @param scrollView A scrollView subclass object informing the delegate.
 @return YES if the empty dataset should fade in.
 */
- (BOOL)emptyDataSetShouldFadeIn:(UIScrollView *)scrollView {
    return true;
}

/**
 Asks the delegate to know if the empty dataset should still be displayed when the amount of items is more than 0. Default is NO
 
 @param scrollView A scrollView subclass object informing the delegate.
 @return YES if empty dataset should be forced to display
 */
- (BOOL)emptyDataSetShouldBeForcedToDisplay:(UIScrollView *)scrollView {
    return false;
}

/**
 Asks the delegate to know if the empty dataset should be rendered and displayed. Default is YES.
 
 @param scrollView A scrollView subclass object informing the delegate.
 @return YES if the empty dataset should show.
 */
- (BOOL)emptyDataSetShouldDisplay:(UIScrollView *)scrollView {
    return true;
}

/**
 Asks the delegate for touch permission. Default is YES.
 
 @param scrollView A scrollView subclass object informing the delegate.
 @return YES if the empty dataset receives touch gestures.
 */
- (BOOL)emptyDataSetShouldAllowTouch:(UIScrollView *)scrollView {
    return true;
}

/**
 Asks the delegate for scroll permission. Default is NO.
 
 @param scrollView A scrollView subclass object informing the delegate.
 @return YES if the empty dataset is allowed to be scrollable.
 */
- (BOOL)emptyDataSetShouldAllowScroll:(UIScrollView *)scrollView {
    return false;
}

/**
 Asks the delegate for image view animation permission. Default is NO.
 Make sure to return a valid CAAnimation object from imageAnimationForEmptyDataSet:
 
 @param scrollView A scrollView subclass object informing the delegate.
 @return YES if the empty dataset is allowed to animate
 */
- (BOOL)emptyDataSetShouldAnimateImageView:(UIScrollView *)scrollView {
    return false;
}

/**
 Tells the delegate that the empty dataset view was tapped.
 Use this method either to resignFirstResponder of a textfield or searchBar.
 
 @param scrollView A scrollView subclass informing the delegate.
 @param view the view tapped by the user
 */
- (void)emptyDataSet:(UIScrollView *)scrollView didTapView:(UIView *)view {
    
}

/**
 Tells the delegate that the action button was tapped.
 
 @param scrollView A scrollView subclass informing the delegate.
 @param button the button tapped by the user
 */
- (void)emptyDataSet:(UIScrollView *)scrollView didTapButton:(UIButton *)button {
    
}

/**
 Tells the delegate that the empty data set will appear.
 
 @param scrollView A scrollView subclass informing the delegate.
 */
- (void)emptyDataSetWillAppear:(UIScrollView *)scrollView {
    
}

/**
 Tells the delegate that the empty data set did appear.
 
 @param scrollView A scrollView subclass informing the delegate.
 */
- (void)emptyDataSetDidAppear:(UIScrollView *)scrollView {
    
}

/**
 Tells the delegate that the empty data set will disappear.
 
 @param scrollView A scrollView subclass informing the delegate.
 */
- (void)emptyDataSetWillDisappear:(UIScrollView *)scrollView {
    
}

/**
 Tells the delegate that the empty data set did disappear.
 
 @param scrollView A scrollView subclass informing the delegate.
 */
- (void)emptyDataSetDidDisappear:(UIScrollView *)scrollView {
    
}

@end
